package servlet.ajax;

import dao.GenericDAO;
import dao.impl.GenericDAOImpl;
import entity.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * Обрабатывает ajax-запросы генерируемые js-приложеннием панели администратора.
 *
 * @author Konstantin Chumachenko <kostyachum@gmail.com>
 */
public class AdminServlet extends HttpServlet {

    @Override
    protected void doPost(final HttpServletRequest request,
            final HttpServletResponse response)
            throws ServletException, IOException {
        JSONObject json = new JSONObject();
        try {
            GenericDAO<OrgUnitType, Long> daoOrgUnitType = new GenericDAOImpl<OrgUnitType, Long>(OrgUnitType.class);
            GenericDAO<Person, Long> daoPerson = new GenericDAOImpl<Person, Long>(Person.class);
            GenericDAO<Phone, Long> daoPhone = new GenericDAOImpl<Phone, Long>(Phone.class);
            GenericDAO<PhoneType, Long> daoPhoneType = new GenericDAOImpl<PhoneType, Long>(PhoneType.class);
            GenericDAO<OrgUnitPost, Long> daoOrgUnitPost = new GenericDAOImpl<OrgUnitPost, Long>(OrgUnitPost.class);
            GenericDAO<OrgUnit, Long> daoOrgUnit = new GenericDAOImpl<OrgUnit, Long>(OrgUnit.class);
            GenericDAO<Post, Long> daoPost = new GenericDAOImpl<Post, Long>(Post.class);
            GenericDAO<Room, Long> daoRoom = new GenericDAOImpl<Room, Long>(Room.class);
            String query = request.getParameter("query");
            /**
             * Список org Unit type
             */
            if (query != null && query.equals("getAutocomplete")) {
                JSONArray jsonUnitType = new JSONArray();
                JSONArray jsonUnit = new JSONArray();
                JSONArray jsonPost = new JSONArray();
                JSONArray jsonPhone = new JSONArray();
                JSONArray jsonRoom = new JSONArray();
                JSONArray jsonPerson = new JSONArray();
                JSONArray jsonUnitPost = new JSONArray();
                JSONArray jsonPhoneType = new JSONArray();
                /*
                 * orgUnitType: id, name.
                 */
                for (OrgUnitType unitType : daoOrgUnitType.getAll()) {
                    List row = new ArrayList();

                    row.add(unitType.getId());
                    row.add(unitType.getName());
                    jsonUnitType.add(row);
                }
                /*
                 * orgUnit: id, name, unitTypeId, perentUnitId.
                 */
                for (OrgUnit unit : daoOrgUnit.getAll()) {
                    List row = new ArrayList();
                    row.add(unit.getId());
                    row.add(unit.getName());
                    try {
                        row.add(unit.getOrgUnitType().getId());
                    } catch (NullPointerException ex) {
                        row.add("-");
                    }
                    try {
                        row.add(unit.getParentUnit().getId());
                    } catch (NullPointerException ex) {
                        row.add("-");
                    }
                    jsonUnit.add(row);
                }
                /*
                 * Post: id, name.
                 */
                for (Post post : daoPost.getAll()) {
                    List row = new ArrayList();
                    row.add(post.getId());
                    row.add(post.getName());
                    jsonPost.add(row);
                }
                /*
                 * Phone: id, number, post ID, typy ID.
                 */
                for (Phone phone : daoPhone.getAll()) {
                    List row = new ArrayList();
                    row.add(phone.getId());
                    row.add(phone.getNumber());
                    row.add(phone.getPost().getId());
                    row.add(phone.getType().getId());

                    jsonPhone.add(row);
                }
                /*
                 * PhoneType: id, name.
                 */
                for (PhoneType phonetype : daoPhoneType.getAll()) {
                    List row = new ArrayList();
                    row.add(phonetype.getId());
                    row.add(phonetype.getName());
                    jsonPhoneType.add(row);
                }
                /*
                 * Room: id, name;
                 */
                for (Room room : daoRoom.getAll()) {
                    List row = new ArrayList();
                    row.add(room.getId());
                    row.add(room.getName());
                    jsonRoom.add(row);
                }
                /*
                 * Person: id, surname, name, patronymic.
                 */
                for (Person person : daoPerson.getAll()) {
                    List row = new ArrayList();
                    row.add(person.getId());
                    row.add(person.getSurname());
                    row.add(person.getName());
                    row.add(person.getFathername());
                    jsonPerson.add(row);
                }
                /*
                 * OrgUnitPost: id, unit id, person id, post id, room id.
                 */
                for (OrgUnitPost unitpost : daoOrgUnitPost.getAll()) {
                    List row = new ArrayList();
                    row.add(unitpost.getId());
                    row.add(unitpost.getOrgUnit().getId());
                    row.add(unitpost.getPerson().getId());
                    row.add(unitpost.getPost().getId());
                    row.add(unitpost.getRoom().getId());
                    jsonUnitPost.add(row);
                }
                json.put("orgUnit", jsonUnit);
                json.put("orgUnitType", jsonUnitType);
                json.put("post", jsonPost);
                json.put("phone", jsonPhone);
                json.put("phoneType", jsonPhoneType);
                json.put("room", jsonRoom);
                json.put("person", jsonPerson);
                json.put("orgUnitPost", jsonUnitPost);
            }
            /**
             * Добавить OrgUnitType
             */
            if (query != null && query.equals("addOrgUnitType")) {
                String name = request.getParameter("name");
                OrgUnitType newOUT = new OrgUnitType(name);
                daoOrgUnitType.add(newOUT);
            }
            /**
             * Добавить OrgUnit
             */
            if (query != null && query.equals("addOrgUnit")) {
                String name = request.getParameter("name");
                String unitType = request.getParameter("unitType");
                String perent = request.getParameter("perent");
                Long unitTypeId = Long.parseLong(unitType);

                OrgUnitType type = daoOrgUnitType.getById(unitTypeId);


                OrgUnit perentUnit = null;
                if (perent != null && perent.equals("") && !perent.equals("-") && !perent.equals("null")) {
                    Long perentId = Long.parseLong(perent);
                    perentUnit = daoOrgUnit.getById(perentId);
                }

                OrgUnit newOU = new OrgUnit(name, perentUnit, type);
                daoOrgUnit.add(newOU);
            }
            /*
             * Удалить OrgUnitType
             */
            if (query != null && query.equals("deleteOrgUnitType")) {
                try {
                    String id = request.getParameter("id");
                    OrgUnitType delOUT = daoOrgUnitType.getById(Long.parseLong(id));
                    System.out.println("to DELETE " + delOUT.getName());
                    daoOrgUnitType.delete(delOUT);

                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить OrgUnitType:\n" + ex.getMessage());
                }
            }
            /*
             * Удалить OrgUnit
             */
            if (query != null && query.equals("deleteOrgUnit")) {
                try {
                    String id = request.getParameter("id");
                    OrgUnit delOU = daoOrgUnit.getById(Long.parseLong(id));
                    System.out.println("to DELETE " + delOU.getName());
                    daoOrgUnit.delete(delOU);

                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить OrgUnit:\n" + ex.getMessage());
                }
            }
            /*
             * Доавбить Post
             */
            if (query != null && query.equals("addPost")) {
                try {
                    String name = request.getParameter("name");
                    Post post = new Post();
                    post.setName(name);
                    daoPost.add(post);

                } catch (Exception ex) {
                    json.put("error", "Не удалось добавить Post:\n" + ex.getMessage());
                }
            }
            /*
             * Удалить Post
             */
            if (query != null && query.equals("deletePost")) {
                try {
                    String id = request.getParameter("id");
                    Post post = new Post();
                    post.setId(Long.parseLong(id));
                    daoPost.delete(post);

                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить Post:\n" + ex.getMessage());
                }
            }
            /*
             * Доавбить PhoneType
             */
            if (query != null && query.equals("addPhoneType")) {
                try {
                    String name = request.getParameter("name");
                    PhoneType ptype = new PhoneType();
                    ptype.setName(name);
                    daoPhoneType.add(ptype);

                } catch (Exception ex) {
                    json.put("error", "Не удалось добавить PhoneType:\n" + ex.getMessage());
                }
            }
            /*
             * Удалить PhoneType
             */
            if (query != null && query.equals("deletePhoneType")) {
                try {
                    String id = request.getParameter("id");
                    PhoneType ptype = new PhoneType();
                    ptype.setId(Integer.parseInt(id));
                    daoPhoneType.delete(ptype);

                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить PhoneType:\n" + ex.getMessage());
                }
            }
            /*
             * Доавбить Phone
             */
            if (query != null && query.equals("addPhone")) {
                try {
                    String number = request.getParameter("number");
                    String unitPost = request.getParameter("unitPost");
                    String type = request.getParameter("type");
                    Phone phone = new Phone();
                    PhoneType phoneType = new PhoneType();
                    OrgUnitPost orgUnitPost = new OrgUnitPost();

                    phoneType.setId(Integer.parseInt(type));
                    orgUnitPost.setId(Long.parseLong(unitPost));

                    phone.setNumber(number);
                    phone.setPost(orgUnitPost);
                    phone.setType(phoneType);

                    daoPhone.add(phone);
                } catch (Exception ex) {
                    json.put("error", "Не удалось добавить Post:\n" + ex.getMessage());
                }
            }
            /*
             * Удалить Phone
             */
            if (query != null && query.equals("deletePhone")) {
                try {
                    String id = request.getParameter("id");
                    Phone phone = new Phone();
                    phone.setId(Long.parseLong(id));
                    daoPhone.delete(phone);
                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить Phone:\n" + ex.getMessage());
                }
            }
            /*
             * Добавление Room
             */
            if (query != null && query.equals("addRoom")) {
                try {
                    String name = request.getParameter("name");
                    Room room = new Room();
                    room.setName(name);
                    daoRoom.add(room);
                } catch (Exception ex) {
                    json.put("error", "Не удалось добавить Room:\n" + ex.getMessage());
                }
            }
            /*
             * Удалить Room
             */
            if (query != null && query.equals("deleteRoom")) {
                try {
                    String id = request.getParameter("id");
                    Room room = new Room();
                    room.setId(Long.parseLong(id));
                    daoRoom.delete(room);
                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить Room:\n" + ex.getMessage());
                }
            }
            /*
             * Добавление Person
             */
            if (query != null && query.equals("addPerson")) {
                try {
                    String name = request.getParameter("name");
                    String surname = request.getParameter("surname");
                    String patronymic = request.getParameter("patronymic");
                    Person person = new Person();
                    person.setName(name);
                    person.setSurname(surname);
                    person.setFathername(patronymic);

                    daoPerson.add(person);
                } catch (Exception ex) {
                    json.put("error", "Не удалось добавить Person:\n" + ex.getMessage());
                }
            }
            /*
             * Удалить Person
             */
            if (query != null && query.equals("deletePerson")) {
                try {
                    String id = request.getParameter("id");
                    Person person = new Person();
                    person.setId(Long.parseLong(id));
                    daoPerson.delete(person);
                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить Person:\n" + ex.getMessage());
                }
            }
            /*
             * Добавление OrgUnitPost
             */
            if (query != null && query.equals("addOrgUnitPost")) {
                try {
                    String unitId = request.getParameter("orgUnitId");
                    String personId = request.getParameter("personId");
                    String roomId = request.getParameter("roomId");
                    String postId = request.getParameter("postId");
                    OrgUnitPost oup = new OrgUnitPost();

                    OrgUnit unit = new OrgUnit();
                    Room room = new Room();
                    Person person = new Person();
                    Post post = new Post();

                    unit.setId(Long.parseLong(unitId));
                    person.setId(Long.parseLong(personId));
                    room.setId(Long.parseLong(roomId));
                    post.setId(Long.parseLong(postId));

                    oup.setOrgUnit(unit);
                    oup.setPerson(person);
                    oup.setRoom(room);
                    oup.setPost(post);
                    daoOrgUnitPost.add(oup);
                } catch (Exception ex) {
                    json.put("error", "Не удалось добавить OrgUnitPost:\n" + ex.getMessage());
                }
            }
            /*
             * Удалить Person
             */
            if (query != null && query.equals("deleteOrgUnitPost")) {
                try {
                    String id = request.getParameter("id");
                    OrgUnitPost orgUnitPost = new OrgUnitPost();
                    orgUnitPost.setId(Long.parseLong(id));
                    daoOrgUnitPost.delete(orgUnitPost);
                } catch (Exception ex) {
                    json.put("error", "Не удалось удалить OrgUnitPost:\n" + ex.getMessage());
                }
            }
            /*
             * Добавить все
             */
            if (query != null && query.equals("addAll")) {
                String name = request.getParameter("name");
                String surname = request.getParameter("surname");
                String patronymic = request.getParameter("patronymic");
                String phone = request.getParameter("phone");
                String phonetype = request.getParameter("phoneType");
                String room = request.getParameter("room");
                String post = request.getParameter("post");
                String unit = request.getParameter("unit");

                OrgUnitPost orgUnitPostEntity = new OrgUnitPost();
                Person personEntity = new Person();
                Phone phoneEntity = new Phone();
                PhoneType phoneTypeEntity = new PhoneType();
                Room roomEntity = new Room();
                Post postEntity = new Post();
                OrgUnit unitEntity = new OrgUnit();

                personEntity.setFathername(patronymic);
                personEntity.setName(name);
                personEntity.setSurname(surname);

                /**
                 * Проверка существования Person
                 */
                List<Person> personCheck = (List<Person>) daoPerson.getByPerson(personEntity);
                if (personCheck.size() == 0) {
                    daoPerson.add(personEntity);
                    personEntity = (Person) (daoPerson.getByPerson(personEntity).toArray()[0]);
                } else {
                    personEntity = (Person) personCheck.toArray()[0];
                }

                /**
                 * Проверка существования PhoneType
                 */
                phoneTypeEntity.setName(phonetype);
                PhoneType phoneTypeCheck = daoPhoneType.getByPhoneTypeByName(phonetype);
                System.out.println("check loaded");
                if (phoneTypeCheck != null) {
                    phoneTypeEntity = phoneTypeCheck;
                } else {
                    daoPhoneType.add(phoneTypeEntity);
                    phoneTypeEntity = daoPhoneType.getByPhoneTypeByName(phonetype);
                }
                /*
                 * Проверка существования Room
                 */
                roomEntity.setName(room);
                List<Room> roomCheck = (List<Room>) daoRoom.getByRoom(roomEntity);
                System.out.println("room check loaded");
                if (roomCheck.size() == 0) {
                    System.out.println("room size = 0");
                    daoRoom.add(roomEntity);
                    roomEntity = (Room) (daoRoom.getByRoom(roomEntity).toArray()[0]);
                } else {
                    roomEntity = roomCheck.get(0);
                }
                /*
                 * Проверка Post
                 */
                postEntity.setName(post);
                List<Post> postCheck = daoPost.getByPost(postEntity);
                System.out.println("post check loaded");
                if (postCheck == null || postCheck.size() == 0) {
                    System.out.println("check == 0 ");
                    daoPost.add(postEntity);
                    postEntity = (Post) (daoPost.getByPost(postEntity).toArray()[0]);
                } else {
                    postEntity = postCheck.get(0);
                }
                /*
                 * Проверка orgUnit
                 */
                unitEntity.setName(unit);
                List<OrgUnit> orgUnitList = (List<OrgUnit>) daoOrgUnit.getByOrgUnit(unitEntity);
                System.out.println("orgUnit check loaded");
                if (orgUnitList.size() == 0) {
                    System.out.println("check 0");
                    daoOrgUnit.add(unitEntity);
                    unitEntity = (OrgUnit) daoOrgUnit.getByOrgUnit(unitEntity).toArray()[0];
                } else {
                    unitEntity = orgUnitList.get(0);
                }
                orgUnitPostEntity.setPerson(personEntity);
                orgUnitPostEntity.setPost(postEntity);
                orgUnitPostEntity.setOrgUnit(unitEntity);
                orgUnitPostEntity.setRoom(roomEntity);
                OrgUnitPost oupTest = daoOrgUnitPost.getOrgUnitPostByOrgUnitPost(orgUnitPostEntity);
                if (oupTest != null) {
                    orgUnitPostEntity = oupTest;
                } else {
                    daoOrgUnitPost.add(orgUnitPostEntity);
                }

                /*
                 * Проверка Phone
                 */
                phoneEntity.setNumber(phone);
                phoneEntity.setPost(orgUnitPostEntity);
                phoneEntity.setType(phoneTypeEntity);
                Phone p = daoPhone.getByPhone(phoneEntity);
                System.out.println("phone check loaded");
                if (p == null) {
                    System.out.println("check 0");
                    daoPhone.add(phoneEntity);
                    phoneEntity = daoPhone.getByPhone(phoneEntity);
                } else {
                    phoneEntity = p;
                }
            }
            /*
             * Формирование ответа
             */
            String sEcho = request.getParameter("sEcho");
            String iLength = request.getParameter("iDisplayLength");
            int length = 1;
            try {
                length = Integer.parseInt(iLength);
            } catch (Exception ex) {
                length = 10;
            }
        } catch (Exception err) {
            err.printStackTrace();
            json.put("error", "big error: " + err.getMessage());
        }
        /*
         * Отправка ответа
         */
        System.out.println(json);
        PrintWriter pw = response.getWriter();
        response.setContentType("text/plain");
        pw.println("" + json.toString() + "");
        pw.flush();
        pw.close();
    }
}
